﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using ChessGameV2.AI;
using ChessGameV2.Scenes;

namespace ChessGameV2
{
    public enum PlayerType { Human, Computer, Server };
    public enum PlayerColor { White, Black };
    public enum PlayerState { Win, Draw, Lost, firstThinking, Thinking, Waiting };

    public class Player
    {
        PlayerType _type;
        PlayerColor _color;
        int _player;
        PlayerState _playerState;  //Trang thai Player
        Move _move;
        public int time; // Bien Time
        Thinking thinking;
        
        #region properties
        public Move move
        {
            get
            {
                return _move;
            }
            set
            {
                this._move = value;
            }
        }
        public PlayerType type
        {
            get
            {
                return _type;
            }
        }
        public PlayerColor color
        {
            get
            {
                return _color;
            }
        }
        public int id
        {
            get
            {
                return _player;
            }
        }
        public PlayerState playerState
        {
            get
            {
                return _playerState;
            }
            set
            {
                this._playerState = value;
            }
        }
        #endregion

        /// <summary>
        /// Ham tao Player
        /// </summary>
        /// <param name="_p">Mau quan co</param>
        /// <param name="_t">Doi tuong nguoi choi ?May, Nguoi, Server</param>
        public Player(int _p,PlayerType _t)
        {
            this._player = _p;
            this._type = _t;
            if(_p ==1 ) this._color = PlayerColor.White;
            else this._color = PlayerColor.Black;
            _playerState = PlayerState.Waiting;
        }
        /// <summary>
        /// Ham kiem tra trang thai bai co
        /// </summary>
        /// <param name="listmove"></param>
        /// <param name="pColor"></param>
        /// <param name="Board"></param>
        /// <returns></returns>
        public void checkState(Moves listmove, int[] Board)
        {
            bool check = listmove.isCheck(this._player, Board);
            if (check && (listmove == null || listmove.Count == 0))
            {
                this._playerState = PlayerState.Lost;
                return;
            }
            if (!check && (listmove == null || listmove.Count == 0))
            {
                this._playerState = PlayerState.Draw;
                return;
            }
            this._playerState = PlayerState.Thinking;
        }
        /// <summary>
        /// Ham thuc hien viec di chuyen quan co tren ban co
        /// </summary>
        /// <param name="board"></param>
        public void ExecuteMove(int[] board)
        {
            if (this._move == null)
            {
                playerState = PlayerState.Lost;
                return;
            }
            //bat su kien am thanh
            if (board[this._move.End] == 0) Sounds.Move();
            else Sounds.CaptureMove();
            this.move.ExecuteMove(board);

            thinking = null;
            //Castling.execute(this.start, this.end);
            ChangeWaiting();
        }
        /// <summary>
        /// Ham thuc hien viec di chuyen cua may
        /// </summary>
        /// <param name="board"></param>
        /// <param name="listmove"></param>
        public void Thinking(int[] board, List<Move> listmove)
        {
            if (thinking == null) thinking = new Thinking(board, listmove, this._player);
            thinking.execThinking();
            //this.test = thinking.test;
            if (time <= 0 || thinking.process.ThreadState == ThreadState.Stopped)
            {
                thinking.arbort();
                this.move = thinking.theBestMove;
                thinking = null;
                ExecuteMove(board);
                return;
            }
            else
            {
                this._move = null;
            }
        }
        /// <summary>
        /// Ham thuc xu li nuoc di chuyen cua nguoi
        /// </summary>
        /// <param name="board"></param>
        /// <param name="listmove"></param>
        /// <param name="temp"></param>
        public void ExecutebyHuman(int[] board,List<Move> listmove, int temp)
        {
            if (time <= 0)
            {
                this._playerState = PlayerState.Lost;
                return;
            }   
            if(this._move == null) 
            {
                this._move = new Move();
                this._move.Player = this._player;
                this._move.Start = int.MinValue;
            }

            if (temp != int.MaxValue)
            {
                if (this._move.Start == int.MinValue || this._move.Start == temp) // Chuot nhan vao o can di chuyen !
                {
                    move.Start = temp;
                    if (getColor(board[temp]) != this._player || board[temp] == 0 || board[temp] == 99)
                        this._move.Start = int.MinValue;
                }
                else if (getColor(board[temp]) == this._player)
                    this._move.Start = temp;  // Thay doi quan co di chuyen
                else
                {
                    this._move.End = temp;
                    Move _return = isvalid(this._move, listmove);
                    if (_return != null)
                    {
                        this._move = _return;
                        ExecuteMove(board);
                    }
                    else this._move.Start = int.MinValue;
                }
            }                   
        }
        /// <summary>
        /// Kiem tra xem nuoc di co hop le
        /// </summary>
        /// <param name="move"></param>
        /// <param name="listmove"></param>
        /// <returns></returns>
        private Move isvalid(Move move,List<Move> listmove)
        {
            Move _return = null;
            if (listmove == null || listmove.Count == 0) return _return;
            foreach (Move m in listmove)
            {
                if (m.Player == move.Player && m.Start == move.Start && m.End == move.End)
                {
                    _return = m;
                    break;
                }
            }
            return _return;
        }
        /// <summary>
        /// Tra ve mau cua quan co tai vi tri index
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        private int getColor(int index)
        {
            return (index % 100) / 10;
        }
        /// <summary>
        /// Chuyen trang thai Player sang trang thai cho
        /// </summary>
        public void ChangeWaiting()
        {
            this._move = null;
            this._playerState = PlayerState.Waiting;
        }
        /// <summary>
        /// Ham lang nghe buoc di cua doi thu
        /// (Thi dau qua Lan)
        /// </summary>
        /// <returns></returns>
        public Move listen()
        {
            return null;
        }
    }
}